package xyz.myachin.saveto.logic.intent

import android.content.Intent
import android.net.Uri
import android.os.Parcelable
import xyz.myachin.saveto.settings.Settings
import java.net.URLDecoder
import kotlin.text.Charsets.UTF_8

class IncomingIntent(private val intent: Intent) {
    lateinit var streamDataUri: Uri
        private set

    private var intentText: String? = null
    private var isHtml = false

    internal var mimeType
        get() = intent.type!!
        set(value) {
            intent.type = value
        }

    internal val text: String
        get() = intent.getStringExtra(Intent.EXTRA_TEXT)!!

    internal var removeFileId = -1L
        private set

    enum class FilterResult {
        URL,
        TEXT,
        FILE_OK,
        FILE_DAMAGED,
        NOT_FOR_ME,
    }

    fun recognizeIntent(): FilterResult {
        if (intent.type.isNullOrBlank()) return FilterResult.NOT_FOR_ME

        if (intent.hasExtra(Intent.EXTRA_STREAM)) {
            streamDataUri = intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as Uri
            removeFileId = intent.getLongExtra(EXTRA_FILE_ID, -1L)

            if (intent.type!!.endsWith("/*")) {
                return FilterResult.FILE_DAMAGED
            }

            return FilterResult.FILE_OK
        }

        if (!intent.getStringExtra(Intent.EXTRA_TEXT).isNullOrBlank()) {
            when {
                !intent.getStringExtra(Intent.EXTRA_HTML_TEXT).isNullOrBlank() -> {
                    intent.getStringExtra(Intent.EXTRA_HTML_TEXT)
                    isHtml = true
                }
                else -> intentText = intent.getStringExtra(Intent.EXTRA_TEXT)
            }

            if (!Settings.useDownloader || !intent.getStringExtra(Intent.EXTRA_TEXT)!!
                    .contains(
                        Regex("^https?://", RegexOption.IGNORE_CASE)
                    )
            ) {
                return FilterResult.TEXT
            }
            return FilterResult.URL
        }

        if(intent.data != null){
            val uri = intent.data!!
            if ((uri.scheme != "file" && uri.scheme != "content")) {
                return FilterResult.NOT_FOR_ME
            }
            streamDataUri = uri
            removeFileId = intent.getLongExtra(EXTRA_FILE_ID, -1L)
            return FilterResult.FILE_OK
        }

        return FilterResult.NOT_FOR_ME
    }

    fun suggestName(): String {
        if (intent.hasExtra(EXTRA_ORIGINAL_URI)) {
            return Uri.parse(intent.getStringExtra(EXTRA_ORIGINAL_URI)!!).lastPathSegment!!
        }

        if (!intentText.isNullOrEmpty()) {
            if (Settings.textLength > -1) {
                return intentText!!
                    .take(Settings.textLength)
                    .clean().apply {
                        if (isHtml) {
                            return plus(".html")
                        }
                        plus(".txt")
                    }
            }
            return "TextFile.txt"
        }

        var startName = "FileName"
        val uri = streamDataUri
        val path = uri.path

        if (path != null) {
            val search = "?filename="
            when {
                path.contains(search) -> startName =
                    path.substringAfter(search).substringBefore("/")
                !uri.lastPathSegment.isNullOrBlank() -> {
                    return URLDecoder.decode(uri.lastPathSegment, UTF_8.name())
                        .substringAfterLast("/").clean()
                }
            }
        }

        return when {
            mimeType == "application/x-bzip2" -> "$startName.bz2"
            mimeType == "application/gzip" -> "$startName.gz"
            mimeType == "application/vnd.rar" -> "$startName.rar"
            mimeType == "application/x-tar" -> "$startName.tar"
            mimeType == "application/zip" -> "$startName.zip"
            mimeType == "application/x-7z-compressed" -> "$startName.7z"
            mimeType == "text/plain" -> "$startName.txt"
            mimeType == "application/x-abiword" -> "$startName.abw"
            mimeType == "application/msword" -> "$startName.doc"
            mimeType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" -> "$startName.docx"
            mimeType == "application/vnd.oasis.opendocument.presentation" -> "$startName.odp"
            mimeType == "application/vnd.oasis.opendocument.spreadsheet" -> "$startName.ods"
            mimeType == "application/vnd.oasis.opendocument.text" -> "$startName.odt"
            mimeType == "application/pdf" -> "$startName.pdf"
            mimeType == "application/vnd.ms-powerpoint" -> "$startName.ppt"
            mimeType == "application/vnd.openxmlformats-officedocument.presentationml.presentation" -> "$startName.pptx"
            mimeType == "application/vnd.visio" -> "$startName.vsd"
            mimeType == "application/vnd.ms-excel" -> "$startName.xls"
            mimeType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" -> "$startName.xlsx"
            mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/") -> {
                "$startName.${mimeType.split("/").last()}"
            }
            else -> "$startName.bin"
        }
    }

    private fun String.clean(): String {
        return this.trim()
            .replace("?", "_")
            .replace("*", "_")
            .replace("/", "_")
            .replace("\\", "_")
            .replace(":", "_")
    }
}
